import { gameConfigHandle } from "core/config/gameConfig"
import { PlayerModel } from "core/model/playerModel"
import playerHandle from "./playerHandle"
import utils from "core/utils/utils"
import equipmentHandle from "./equipmentHandel"
import Random from "core/utils/random"
import skillHandle from "./skillHandle"
import bagHandle from "./bagHandle"
import { TreasureItemModel } from "core/model/treasureModel"
import { AttriType, MapType } from "core/typeDefine/typeDefine"
import gameUtils from "core/utils/gameUtils"
import petHandle from "./petHandle"

class AdventureHandle {
    constructor() {

    }

    adventureSettle(player: PlayerModel, floor: number, getData, random: Random) {
        let adventureConfig = gameConfigHandle.gameConfig.adventure
        let addEquipmentFlag = false
        if (floor >= 15 && floor < 50 && floor % 1 == 0) {
            addEquipmentFlag = true
        } else if (floor >= 50 && floor % 2 == 0) {
            addEquipmentFlag = true
        }
        if (addEquipmentFlag) {
            let item = equipmentHandle.create(player, null, random, {})
            let destroy = false
            if (player.adventure.equipmentAutoDestroy[item.equipment.quality]) {
                destroy = true
            } else {
                let res = bagHandle.addItemComponent(player.equipmentBag, item)
                if (!res) {
                    destroy = true
                }
            }
            if (destroy) {
                let destroyGet = equipmentHandle.destroy(player, item)
                getData.destroyGet = destroyGet
            } else {
                getData.equipmentAmount += 1
            }
        }
        // let addSkillFlag = false
        // if (floor <= 5 && floor % 3 == 0) {
        //     addSkillFlag = true
        // } else if (floor >= 6 && floor < 20 && floor % 5 == 0) {
        //     addSkillFlag = true
        // } else if (floor >= 20 && floor < 50 && floor % 7 == 0) {
        //     addSkillFlag = true
        // } else if (floor >= 50 && floor < 100 && floor % 10 == 0) {
        //     addSkillFlag = true
        // } else if (floor >= 100 && floor < 500 && floor % 13 == 0) {
        //     addSkillFlag = true
        // } else if (floor >= 500 && floor % 15 == 0) {
        //     addSkillFlag = true
        // }

        // if (addSkillFlag) {
        //     getData.skillBookAmount += 1
        //     let item = skillHandle.createBook(random, { minQuality: 0, maxQuality: 2 })
        //     let res = bagHandle.addItemComponent(player.skillBag, item)
        // }

        adventureConfig.getResources.forEach((name) => {
            let values = adventureConfig.getResourceByFloor[name]
            let amount = adventureConfig.dropGoldAmount
            let value = utils.getIncValues(values, player.adventure.floor) * amount
            value = Math.floor(value)
            if (!getData.mapGet[name]) {
                getData.mapGet[name] = 0
            }
            getData.mapGet[name] += value
            if (typeof name == 'number') {
                bagHandle.addItem(player.bag, name, value)
            } else {
                player.itemInfo[name] += value
            }
        })
        adventureConfig.adventureDropItems.forEach(item => {
            if (item.itemID) {
                if (item.limitFloor) {
                    if (floor < item.limitFloor) {
                        return
                    }
                }
                if (item.limitMapID) {
                    if (gameUtils.isMapLimit(player, item.limitMapID)) {
                        return
                    }
                }
                if (floor && floor % item.floorInterval == 0) {
                    let amount = utils.getIncValues(item.amount, floor)
                    if (amount > (item.maxAmount || 0)) {
                        amount = item.maxAmount
                    }
                    if (typeof item.itemID == 'number') {
                        bagHandle.addItem(player.bag, item.itemID, amount as number)
                    } else {
                        player.itemInfo[item.itemID] += amount as number
                    }

                    getData.mapGet[item.itemID] = amount
                }
            }

        })
        let diamond = utils.getIncValues(adventureConfig.adventureDiamondGet, 1)
        player.itemInfo.diamond += diamond
        getData.mapGet['diamond'] = diamond
    }

    getGoldResoureAdd(player: PlayerModel, isMonthVip: boolean, isYearVip: boolean) {
        let resourceAdd = adventureHandle.getAdventureAddPer(player, isMonthVip,isYearVip)
        let adventureConfig = gameConfigHandle.gameConfig.adventure
        let values = adventureConfig.getResourceByFloor.gold
        let maxTotal = this.getAdventureMapProgress(player).total//之前是 maxTotal
        let value = utils.getIncValues(values, maxTotal)
        if (maxTotal > 4050) {
            maxTotal = Math.floor(4050 + (maxTotal - 4050) * 0.2)
            value = utils.getIncValues(values, maxTotal)
        }
        // console.log(value, resourceAdd, player.adventure.onLineGetGold, player.adventure.addGoldPer)
        value = Math.floor(value + value * resourceAdd / 100 + player.adventure.onLineGetGold)
        //套装提升的金币收益
        value = Math.floor(value * (1 + (player.adventure.addGoldPer || 0) / 100))
        // console.log(value,maxTotal)
        return value
    }

    getGoldResoureOriginAdd(player: PlayerModel) {
        let adventureConfig = gameConfigHandle.gameConfig.adventure
        let values = adventureConfig.getResourceByFloor.gold
        let maxTotal = this.getAdventureMapProgress(player).total
        let value = utils.getIncValues(values, maxTotal)
        if (maxTotal > 4050) {
            maxTotal = Math.floor(4050 + (maxTotal - 4050) * 0.1)
            value = utils.getIncValues(values, maxTotal)
        }
        value = Math.floor(value)
        return value
    }

    getResoureAdd(player: PlayerModel, name: string, isMonthVip: boolean, isYearVip: boolean) {
        let resourceAdd = adventureHandle.getAdventureAddPer(player, isMonthVip,isYearVip)
        let adventureConfig = gameConfigHandle.gameConfig.adventure
        let values = adventureConfig.getResourceByFloor[name]
        let researchEquipmentAdd = player.research.researchEquipmentAttris[name]
        let value = utils.getIncValues(values, player.adventure.floor) + researchEquipmentAdd
        value = Math.floor(value + value * resourceAdd / 100 + value * (player.talent.resourceAttris[name] || 0) / 100)
        return value
    }

    calcTalentResoureAdd(player: PlayerModel) {
        let treasureConfig = gameConfigHandle.gameConfig.treasure
        treasureConfig.list.map(treasureid => {
            let treasureItemInfo: TreasureItemModel = player.treasure.list[treasureid]
            if (treasureItemInfo) {
                let treasureItemConfig = gameConfigHandle.configByID[treasureid]
                treasureItemConfig.attris.map((attriItem, i, array) => {
                    let attriName = attriItem.attriName
                    let attriType = attriItem.attriType
                    if (attriType == AttriType.Adventure) {
                        let value = utils.getIncValues(attriItem.values, treasureItemInfo.lvl)
                        if (attriName == 'clickGold') {
                            player.adventure.clickGold = value
                        } else if (attriName == 'onLineGetGold') {
                            // player.adventure.onLineGetGold = value
                        }
                    }
                })
            }

        })
    }

    getInstanceAmount(player: PlayerModel, isMonthVip: boolean) {

        let { vipLvl } = playerHandle.getVip(player)
        let mapConfig = gameConfigHandle.gameConfig.map
        let vipConfig = gameConfigHandle.gameConfig.vip
        let lockAmount = 0
        mapConfig.instanceList.forEach((instanceID) => {
            let mapItemConfig = gameConfigHandle.configByID[instanceID]
            if (!gameUtils.isMapLimit(player, mapItemConfig.limitMapID)) {
                lockAmount += 1
            }
        })
        let maxTimes = utils.getIncValues(mapConfig.instanceAmount, lockAmount) + vipConfig.vipAdd.instanceTimes[vipLvl] + (isMonthVip ? vipConfig.monthVip.instanceTimes : 0)
        return maxTimes
    }

    getAbyssAmount(player: PlayerModel, isMonthVip: boolean) {

        let { vipLvl } = playerHandle.getVip(player)
        let mapConfig = gameConfigHandle.gameConfig.map
        let vipConfig = gameConfigHandle.gameConfig.vip
        let maxTimes = mapConfig.abyssAmount + vipConfig.vipAdd.abyssTimes[vipLvl] + (isMonthVip ? vipConfig.monthVip.abyssTimes : 0)
        return maxTimes
    }

    getWbossMapMotivateTimes(player: PlayerModel, isMonthVip: boolean) {

        let mapConfig = gameConfigHandle.gameConfig.map
        let vipConfig = gameConfigHandle.gameConfig.vip
        let times = mapConfig.motivateTimes
            + vipConfig.vipAdd.motivateTimes[playerHandle.getVip(player).vipLvl]
            + (isMonthVip ? vipConfig.monthVip.motivateTimes : 0)
        return times
    }

    getBossAmount(player: PlayerModel, isMonthVip: boolean) {
        // let { vipLvl } = playerHandle.getVip(player)
        let mapConfig = gameConfigHandle.gameConfig.map
        let vipConfig = gameConfigHandle.gameConfig.vip
        let maxTimes = mapConfig.bossTimes
            // + vipConfig.vipAdd.bossTimes[vipLvl]
            + (isMonthVip ? vipConfig.monthVip.bossTimes : 0)
            + player.adventure.bossMapData.motivateLvl
        return maxTimes
    }

    getxunbaoAmount(player: PlayerModel, isMonthVip: boolean) {
        let { vipLvl } = playerHandle.getVip(player)
        let vipConfig = gameConfigHandle.gameConfig.vip
        let maxTimes = 0 //gameConfigHandle.gameConfig.luck.xbDiamondTimesMax + vipConfig.vipAdd.xunbaoTimes[vipLvl] + (isMonthVip ? vipConfig.monthVip.xunbaoTimes : 0)
        return maxTimes
    }

    getxunbaoDiamondAmount(player: PlayerModel, isMonthVip: boolean) {
        let { vipLvl } = playerHandle.getVip(player)
        let vipConfig = gameConfigHandle.gameConfig.vip
        let maxTimes = 0 //gameConfigHandle.gameConfig.luck.xbTimesMax + vipConfig.vipAdd.xunbaoDiamondTimes[vipLvl] + (isMonthVip ? vipConfig.monthVip.xunbaoDiamondTimes : 0)
        return maxTimes
    }

    getAdventureAddPer(player: PlayerModel, isMonthVip: boolean, isYearVip: boolean) {
        let { vipLvl } = playerHandle.getVip(player)

        let vipConfig = gameConfigHandle.gameConfig.vip
        let resoureAdd = vipConfig.vipAdd.resoureAdd[vipLvl] + (isMonthVip ? vipConfig.monthVip.resoureAdd : 0) + (isYearVip ? vipConfig.yearVip.resoureAdd : 0)
        return resoureAdd
    }

    getMagiceMachineFreeTimes(player: PlayerModel, isMonthVip: boolean) {
        let { vipLvl } = playerHandle.getVip(player)
        let vipConfig = gameConfigHandle.gameConfig.vip
        let magicMachineConfig = gameConfigHandle.gameConfig.magicMachine
        let resoureAdd = 0 //magicMachineConfig.freeTimes + (isMonthVip ? vipConfig.monthVip.magiceMachineFreeTimes : 0)
        return resoureAdd
    }

    getAdventureExploreTotalTimes(player: PlayerModel) {
        let total = 0
        let mapConfig = gameConfigHandle.gameConfig.map
        mapConfig.mapList.forEach((mapID) => {
            let value = player.adventure.mapExploreProgress[mapID]
            if (value) {
                total += value as number
            }
        })
        return total
    }

    getAdventureMapProgress(player: PlayerModel) {
        let total = 0
        let mapConfig = gameConfigHandle.gameConfig.map
        let maxTotal = 0
        mapConfig.mapList.forEach((mapID) => {
            let value = player.adventure.mapProgress[mapID]
            if (value) {
                let mapItemConfig = gameConfigHandle.configByID[mapID]


                if (value > mapItemConfig.maxFloor) {
                    maxTotal += mapItemConfig.maxFloor
                    if (mapID == mapConfig.endlessMapID) {
                        total += value as number
                    } else {
                        total += mapItemConfig.maxFloor
                    }
                } else {
                    maxTotal += value as number
                    total += value as number
                }

            }
        })
        return { total, maxTotal }
    }

    getMapMonsterLvl(mapID: number, floor: number) {
        let monsterLvl = 0, monsterMaxLvl = 0
        let mapConfig = gameConfigHandle.gameConfig.map
        for (let i = 0; i < mapConfig.mapList.length; i++) {
            let _mapID = mapConfig.mapList[i]
            let mapItemConfig = gameConfigHandle.configByID[_mapID]
            if (_mapID !== mapID) {
                monsterLvl += mapItemConfig.maxFloor
                monsterMaxLvl += mapItemConfig.maxFloor
            } else {
                if (floor > mapItemConfig.maxFloor) {
                    monsterMaxLvl += mapItemConfig.maxFloor
                } else {
                    monsterMaxLvl += floor
                }
                monsterLvl += floor
                break;
            }
        }

        return { monsterLvl, monsterMaxLvl }
    }

    getAdventureExploreIngMaxAmount(player: PlayerModel) {
        let mapConfig = gameConfigHandle.gameConfig.map
        let { maxTotal } = this.getAdventureMapProgress(player)

        let mapExploreMaxAmount = 1
        for (let i = 0; i < mapConfig.mapExploreMaxAmount.length; i++) {
            let times = mapConfig.mapExploreMaxAmount[i]
            if (maxTotal >= times) {
                mapExploreMaxAmount += 1
            } else {
                break
            }
        }
        return mapExploreMaxAmount
    }

    getUnLockMapAmount(player: PlayerModel) {
        let mapConfig = gameConfigHandle.gameConfig.map
        let amount = 0
        mapConfig.mapList.forEach((mapID) => {
            let mapItemConfig = gameConfigHandle.configByID[mapID]
            if (player.adventure.mapProgress[mapID] && player.adventure.mapProgress[mapID] >= mapItemConfig.maxFloor) {
                amount += 1
            }
        })
        return amount
    }

    getHeroLockRate(player: PlayerModel) {
        let recruitConfig = gameConfigHandle.gameConfig.recruit
        let unLockHeroAmount = utils.keys(player.team.lockList).length
        let lockRecruitRate = recruitConfig.lockRecruitRate[unLockHeroAmount]
        if (!lockRecruitRate) {
            lockRecruitRate = recruitConfig.otherLockRecruitRate
        }
        let heroList = [[], [], []]
        recruitConfig.recruitList.forEach(herotid => {
            let heroItemConfig = gameConfigHandle.configByID[herotid]
            if (!player.team.lockList[herotid]) {
                heroList[heroItemConfig.quality].push(herotid)
            }
        })
        lockRecruitRate = lockRecruitRate.slice(0)
        if (heroList[0].length == 0) {
            lockRecruitRate[1] = lockRecruitRate[0] + lockRecruitRate[1]
            lockRecruitRate[0] = 0
            if (heroList[1].length == 0) {
                lockRecruitRate[2] = lockRecruitRate[1] + lockRecruitRate[2]
                lockRecruitRate[1] = 0
            }
        } else if (heroList[1].length == 0) {
            lockRecruitRate[0] = lockRecruitRate[0] + lockRecruitRate[1]
            lockRecruitRate[1] = 0
        } else if (heroList[2].length == 0) {
            lockRecruitRate[0] = lockRecruitRate[0] + lockRecruitRate[2]
            lockRecruitRate[2] = 0
        }
        return lockRecruitRate
    }

    getOnlineMaxTime(player: PlayerModel, isMonthVip: boolean) {

        let { vipLvl } = playerHandle.getVip(player)
        let adventureConfig = gameConfigHandle.gameConfig.adventure
        let vipConfig = gameConfigHandle.gameConfig.vip
        let maxTimes = adventureConfig.onlineMaxTime + vipConfig.vipAdd.onLineTimeAdd[vipLvl] + (isMonthVip ? vipConfig.monthVip.onLineTimeAdd : 0)
        return maxTimes
    }

    getClickGetGoldMaxTimes(player: PlayerModel, isMonthVip: boolean) {

        let { vipLvl } = playerHandle.getVip(player)
        let adventureConfig = gameConfigHandle.gameConfig.adventure
        let vipConfig = gameConfigHandle.gameConfig.vip
        let maxTimes = adventureConfig.clickGetGoldMaxTimes + vipConfig.vipAdd.clickGetGoldMaxTimes[vipLvl] + (isMonthVip ? vipConfig.monthVip.clickGetGoldMaxTimes : 0)
        return maxTimes
    }

    mapIsUnlock(player: PlayerModel, mapID: number) {
        let mapConfig = gameConfigHandle.configByID[mapID]
        if (player.adventure.mapProgress[mapID] && player.adventure.mapProgress[mapID] >= mapConfig.maxFloor) {
            return true
        }
        return false
    }

    getInstanceTotalProgress(player: PlayerModel) {
        let mapConfig = gameConfigHandle.gameConfig.map
        let total = 0
        mapConfig.instanceList.forEach(mapID => {
            total += player.adventure.mapProgress[mapID] || 0
        })
        return total
    }


    instanceSettleItem(player: PlayerModel, mapID: number, floor: number, random: Random) {
        let mapItemConfig = gameConfigHandle.configByID[mapID]
        let mapConfig = gameConfigHandle.gameConfig.map
        let monsterLvl = utils.getIncValues(mapItemConfig.monsterLvl, floor)
        let mapGet = {}, mapGetPet = []
        // if (mapItemConfig.getResource) {
        //    
        //     mapItemConfig.getResource.forEach(item => {
        //         let itemID = item.itemID
        //         let values = item.incValues
        //         let value = utils.getIncValues(values, total) * gameUtils.getResourceAmount(itemID, total)
        //         value = Math.floor(value)
        //         if (!mapGet[itemID]) {
        //             mapGet[itemID] = 0
        //         }
        //         mapGet[itemID] += value
        //         if (typeof itemID == 'number') {
        //             bagHandle.addItem(player.bag, itemID, value)
        //         } else {
        //             player.itemInfo[itemID] += value
        //         }
        //     })
        // }
        let total = adventureHandle.getInstanceTotalProgress(player)
        if (total > 40) {
            total = 40 + (total - 40) / 7
        }

        if (mapItemConfig.mapType !== MapType.WBoss) {
            let gold = mapConfig.instanceGetGold.coe * gameUtils.getResourceAmount('gold', utils.getIncValues(mapConfig.instanceGetGold.incValues, total))
            mapGet["gold"] = gold
            player.itemInfo.gold += gold
        }

        if (mapItemConfig.getItems) {
            mapItemConfig.getItems.forEach(item => {
                let itemID = item.itemID
                if (itemID) {
                    let values = item.incValues
                    let value = utils.getIncValues(values, floor)
                    value = Math.floor(value)
                    if (item.maxAmount && value > item.maxAmount) {
                        value = item.maxAmount
                    }
                    if (!mapGet[itemID]) {
                        mapGet[itemID] = 0
                    }

                    mapGet[itemID] += value
                    bagHandle.addItem(player.bag, itemID, value)
                }
                if (item.itemIDs) {
                    let itemID: number = utils.getOneFromArray(item.itemIDs, random)
                    let values = item.incValues
                    let value = utils.getIncValues(values, floor)
                    value = Math.floor(value)
                    if (item.maxAmount && value > item.maxAmount) {
                        value = item.maxAmount
                    }
                    if (!mapGet[itemID]) {
                        mapGet[itemID] = 0
                    }

                    mapGet[itemID] += value
                    bagHandle.addItem(player.bag, itemID, value)
                }
            })
        }

        if (mapItemConfig.getPet) {
            let petID: number = utils.getOneFromArray(mapItemConfig.getPet, random)
            let item = petHandle.create(petID, floor, random, {})
            bagHandle.addItemComponent(player.petBag, item)
            mapGetPet.push(petID)
            petID = utils.getOneFromArray(mapItemConfig.getPet, random)
            item = petHandle.create(petID, floor, random, {})
            bagHandle.addItemComponent(player.petBag, item)
            mapGetPet.push(petID)
        }

        if (mapItemConfig.getEquipments) {
            for (let i = 0; i < mapItemConfig.getEquipments; i++) {
                let equipmentLvl = Math.floor(equipmentHandle.getEquipmentLvl(monsterLvl) * 1.5)//副本装备等级改成1.5倍
                let lvlMax = gameConfigHandle.gameConfig.equipment.equipmentMaxLvl
                if (equipmentLvl > lvlMax) {
                    equipmentLvl = lvlMax
                }
                let item = equipmentHandle.create(player, null, random, {})
                let floorLvl = item.equipment.lvl
                if (equipmentLvl > floorLvl) {
                    equipmentLvl = floorLvl
                }
                let equipmentItem = equipmentHandle.create(player, 'instance', random, { minQuality: 1, equipmentLvl: equipmentLvl, lucky: floor * 5 })
                let res = bagHandle.addItemComponent(player.equipmentBag, equipmentItem)

            }
        }

        if (mapItemConfig.getSkillBook) {
            for (let i = 0; i < mapItemConfig.getSkillBook; i++) {
                let skillItem = skillHandle.createBook(random, { minQuality: 1, maxQuality: 3 })
                let res = bagHandle.addItemComponent(player.skillBag, skillItem)
            }
        }
        return { mapGet, mapGetPet }
    }

    calcTreasureAdventureAdd(player: PlayerModel) {
        player.adventure.clickGold = 0
        player.adventure.onLineGetGold = 0
        let treasureConfig = gameConfigHandle.gameConfig.treasure
        treasureConfig.list.map(treasureid => {
            let treasureItemInfo: TreasureItemModel = player.treasure.list[treasureid]
            if (treasureItemInfo && treasureItemInfo.lvl > 0) {
                let treasureItemConfig = gameConfigHandle.configByID[treasureid]
                treasureItemConfig.attris.map((attriItem, i, array) => {
                    let attriName = attriItem.attriName
                    let attriType = attriItem.attriType
                    if (attriType == AttriType.Adventure) {
                        let value = utils.getIncValues(attriItem.values, treasureItemInfo.lvl)
                        let star = treasureItemInfo.star || 0
                        let up = 1 + treasureConfig.starUpAttriPer * star / 100
                        value = Math.floor(value * up)
                        if (attriName == 'clickGold') {
                            // player.adventure.clickGold = value
                        } else if (attriName == 'onLineGetGold') {
                            player.adventure.onLineGetGold = value
                        }
                    }
                })
            }

        })
    }
}

let adventureHandle = new AdventureHandle()
export default adventureHandle